"""
线程相关：是调度的最小单位，是进程内的执行单元
1.创建线程  t1 =  threading.Thread(target=task1,name="MJL-Thread-1")
    执行：t1.start()
2. 取出线程名字： threading.current_thread().name
3.

"""
import threading
import time


def task1():
    for i in range(10):
        print(f"当前线程名称：{threading.current_thread().name},第{i}次执行结果")
        time.sleep(0.5)

def task2():
    for i in range(10):
        print(f"当前线程名称：{threading.current_thread().name},第{i}次执行结果")
        time.sleep(0.5)

def task3():
    time.sleep(1)
    print(f"当前线程：{threading.current_thread().name}")

def task4(n,msg):
    for i in range(n):
        print(f"当前线程：{threading.current_thread().name},第{i}次，{msg}")
        time.sleep(0.2)

# 1.场景一：创建线程 ；看起来是按照按照顺序执行，实际是无序的；
def create_task1():
    t1 = threading.Thread(target=task1,name="MJL-Thread-1")
    t2 = threading.Thread(target=task2)

    t1.start()
    t2.start()
    print(f"主线程:{threading.current_thread()}")

# 2.场景二：验证线程执行是无序的（创建5个线程；）,它是由cpu调度哪个线程先执行，没有调度的线程不能执行；
def create_task2():
    for i in range(5):
        t = threading.Thread(target=task3)
        t.start()

# 3.场景三：传参 args kwargs
def create_task3():
    t1 = threading.Thread(target=task4,args=(10,"python"))
    t2 = threading.Thread(target=task4,kwargs={"n":10,"msg":"majialu"})

    t1.start()
    t2.start()

# 4.场景四：线程同步 join()
def create_task4():
    t1 = threading.Thread(target=task4,args=(10,"python"))
    t2 = threading.Thread(target=task4,kwargs={"n":10,"msg":"majialu"})

    t1.start()
    t1.join()  # 线程1执行结束以后才开始执行线程2
    t2.start()

# 5.场景五：守护线程（2） ：无论子进程是否执行完毕，只要是父进程结束，子进程结束
def create_task5():
    t1 = threading.Thread(target=task4,args=(10,"python"),daemon=True) #方式1
    t2 = threading.Thread(target=task4,kwargs={"n":10,"msg":"majialu"})

    t2.daemon = True  # 方式2
    t1.start()
    t2.start()
    time.sleep(1)
    print(threading.current_thread())  # 主线程退出的时候，子线程也退出

# 6.***场景六：线程共享全局变量
# 因此，会出现脏数据问题（python 3.10版本以后，引入新的GIL2.0版本的锁，有效提升了线程的安全问题）
# 解决办法：加互斥锁（缺点：开销大，效率低）
sum = 0
lock = threading.Lock()

def add_one():
    global sum
    for i in range(10000000):
        lock.acquire()  # 加锁，开销大，效率低；不过python3.10以上版本没有复现脏数据问题***
        sum += 1
        lock.release()  # 解锁
    print(f"{threading.current_thread().name} : {sum}")

def create_task6():

    for i in range(50):
        t = threading.Thread(target=add_one)
        t.start()

# 场景7：死锁 就是互斥锁使用不当，一个线程获取锁以后，一直没有释放，导致其他线程无法获取互斥锁，持续进行等待的情况；

if __name__ == '__main__':
    create_task6()





